编写who命令
通过编写who命令来了解 utmp
数据结构, 和Unix文件的打开、读取和关闭
从文件读取数据结构
查找从读取文件相关
$ man -k file | grep read
最有可能的是read(2)
$ man 2 read
这个系统调用可以将文件中一定数目的字节读入缓冲区,
因为每次都要读入一个数据结构,
所以要用sizeof(struct utmp)
来指定每次读入的字节数.
read
需要一个文件描述符作为参数,
在read
的联机帮助中的最后部分有对 open(2)
引用
$ man 2 open
查看 open
的联机帮助, 从open
中又可以找到对 close
的引用
使用open/read和close
1. 打开一个文件: open
这个系统调用在进程和文件之间建立一条连接, 这个连接被称为文件描述符
open | |
---|---|
目标 | 打开一个文件 |
头文件 | #include <fcntl.h> |
函数原型 | int fd = open(char *name, int how) |
参数 | name 文件名 |
how O_RDONLY, O_WRONLY, or O_RDWR | |
返回值 | -1 error int success |
2.从文件读取数据:read
read | |
---|---|
目标 | 把数据读取到缓冲区 |
头文件 | #include <unistd.h> |
函数原型 | size_t numread = read(int fd, void *buf, size_t qty) |
参数 | fd 文件描述, buf 缓冲区, qty 要读取的字节数 |
返回值 | -1 error, numread success |
3. 关闭文件: close
close | |
---|---|
目标 | 关闭一个文件 |
头文件 | #include <unistd.h> |
函数原型 | int result = close(int fd) |
参数 | fd 文件描述符 |
返回值 | -1 error, 0 success |
who1.c
#include <stdio.h> #include <utmp.h> #include <fcntl.h> #include <unistd.h> #include <time.h> #define SHOWHOST void show_time(long); void show_info(struct utmp *); int main() { struct utmp current_record; int utmpfd, reclen = sizeof(current_record); if ((utmpfd = open(UTMP_FILE, O_RDONLY)) == -1) { perror(UTMP_FILE); exit(1); } while (read(utmpfd, ¤t_record, reclen) == reclen){ show_info(¤t_record); } close(utmpfd); return 0; } void show_info(struct utmp * utbufp) { /* * USER_PROCESS 表示一个真实登陆的用户 */ if (utbufp->ut_type != USER_PROCESS) return; // 登陆用户名(教程上是utbufp->ut_name, 实际上是utbufp->ut_user) printf("%-8.8s", utbufp->ut_user); printf(" "); // 登陆的终端(tty1~6或者pts/n) printf("%-8.8s", utbufp->ut_line); // 登陆时间(书上是utbufp->ut_time, 实际上是utbufp->ut_tv.tv_sec) show_time(utbufp->ut_tv.tv_sec); #ifdef SHOWHOST printf("(%s)", utbufp->ut_host); #endif printf("\n"); } void show_time(long timeval) { char *cp; cp = ctime(&timeval); printf("%12.12s", cp + 4); }